package com.bysc.cmsservice.caller;

import cn.hutool.json.JSONUtil;
import com.bysc.baseservice.handler.BaiYunException;
import com.bysc.cmsservice.entity.dto.AiDto;
import com.bysc.cmsservice.entity.vo.CmsAiVo;
import com.bysc.cmsservice.factory.SystemContentStrategyFactory;
import com.bysc.cmsservice.strategy.SystemContentStrategy;
import com.bysc.commonutils.ResultCode;
import lombok.extern.slf4j.Slf4j;
import okhttp3.*;
import org.apache.http.HttpHeaders;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.springframework.stereotype.Component;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.concurrent.TimeUnit;

@Slf4j
@Component
public class BaiDuAiCaller implements AiCaller {

    public static final String API_KEY = "Ir1ZmiPsFYK3nvX6xI7ZN8Ns";
    public static final String SECRET_KEY = "IeUPXcmvDn6tShh9kbfpOnfd9vsIwh7f";
    protected static final OkHttpClient HTTP_CLIENT = new OkHttpClient.Builder()
            .connectTimeout(30, TimeUnit.MINUTES)
            .readTimeout(30, TimeUnit.MINUTES)
            .writeTimeout(30, TimeUnit.MINUTES)
            .build();
    private String accessToken;

    @Override
    public void init() {
        try {
            this.accessToken = getAccessToken();
        } catch (Exception e) {
            log.error("Failed to get access token", e);
            throw new BaiYunException(ResultCode.ERROR, "初始化失败，请联系管理员");
        }
    }

    private String getAccessToken() throws IOException, JSONException {
        MediaType mediaType = MediaType.parse("application/x-www-form-urlencoded");
        RequestBody body = RequestBody.create(mediaType,
                "grant_type=client_credentials&client_id=" + API_KEY + "&client_secret=" + SECRET_KEY);
        Request request = new Request.Builder()
                .url("https://aip.baidubce.com/oauth/2.0/token")
                .post(body)
                .addHeader("Content-Type", "application/x-www-form-urlencoded")
                .build();
        try (Response response = HTTP_CLIENT.newCall(request).execute()) {
            if (!response.isSuccessful()) {
                throw new IOException("Unexpected code " + response);
            }
            return new JSONObject(response.body().string()).getString("access_token");
        }
    }

    @Override
    public void getReply(AiDto aiDto, HttpServletRequest userRequest, HttpServletResponse response) throws Exception {
        MediaType mediaType = MediaType.parse("application/json");
        String[] messages = aiDto.getMessages();
        String scene = aiDto.getScene();
        int length = messages.length;

        response.setHeader(HttpHeaders.CONTENT_TYPE, mediaType.toString());
        response.setCharacterEncoding("UTF-8");
        response.setHeader(HttpHeaders.PRAGMA, "no-cache");
        ServletOutputStream out = null;

        try {
            out = response.getOutputStream();
            if (length <= 0 || length % 2 == 0) {
                throw new BaiYunException(ResultCode.ERROR, "无效问题，请重新输入");
            }

            JSONObject jsonBody = new JSONObject();
            JSONArray jsonArray = new JSONArray();
            for (int i = 0; i < length; i++) {
                JSONObject message = new JSONObject();
                message.put("role", i % 2 == 0 ? "user" : "assistant");
                message.put("content", messages[i]);
                jsonArray.put(message);
            }
            jsonBody.put("messages", jsonArray);

            // 使用工厂模式创建策略
            SystemContentStrategy strategy = SystemContentStrategyFactory.createStrategy(scene);
            jsonBody.put("system", strategy.getSystemContent());
            jsonBody.put("stream", true);
            RequestBody requestBody = RequestBody.create(mediaType, jsonBody.toString());
            Request request = new Request.Builder()
                    .url("https://aip.baidubce.com/rpc/2.0/ai_custom/v1/wenxinworkshop/chat/ernie-speed-128k?access_token=" + accessToken)
                    .post(requestBody)
                    .addHeader("Content-Type", "application/json")
                    .build();

            try (Response resp = HTTP_CLIENT.newCall(request).execute()) {
                if (!resp.isSuccessful()) {
                    throw new IOException("Unexpected code " + resp);
                }
                ResponseBody responseBody = resp.body();
                if (responseBody == null) {
                    throw new IOException("Response body is null");
                }

                // 获取响应体的输入流
                InputStream inputStream = responseBody.byteStream();

                // 逐行读取响应内容
                BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
                String line;
                while ((line = reader.readLine()) != null) {
                    // 去掉前缀 "data: " 和后缀 "\n\n"
                    if (line.startsWith("data: ")) {
                        line = line.substring(6); // 去掉 "data: "
                        try {
                            JSONObject jsonObject = new JSONObject(line);
                            String content = jsonObject.getString("result");
                            Boolean is_end = jsonObject.getBoolean("is_end");
                            CmsAiVo cmsAiVo = new CmsAiVo(content, is_end);
                            System.out.println(cmsAiVo);
                            // 将提取的内容逐步返回给前端
                            out.write(JSONUtil.toJsonStr(cmsAiVo).getBytes("UTF-8"));
                            out.flush();
                        } catch (JSONException e) {
                            log.error("Failed to parse JSON: {}", line, e);
                        }
                    }
                }

                // 关闭资源
                reader.close();
                inputStream.close();
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new BaiYunException(ResultCode.ERROR, "系统内部错误，请联系管理员");
        } finally {
            try {
                if (out != null) {
                    out.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
                throw new BaiYunException(ResultCode.ERROR, "系统内部错误，请联系管理员");
            }
        }
    }
//    @Override
//    public void getReply(AiDto aiDto, HttpServletRequest userRequest, HttpServletResponse response) throws Exception {
//        MediaType mediaType = MediaType.parse("application/json");
//        String[] messages = aiDto.getMessages();
//        String scene = aiDto.getScene();
//        int length = messages.length;
//
//        response.setHeader(HttpHeaders.CONTENT_TYPE, mediaType.toString());
//        response.setCharacterEncoding("UTF-8");
//        response.setHeader(HttpHeaders.PRAGMA, "no-cache");
//        ServletOutputStream out = null;
//
//        try {
//            out = response.getOutputStream();
//            if (length <= 0 || length % 2 == 0) {
//                throw new BaiYunException(ResultCode.ERROR, "无效问题，请重新输入");
//            }
//
//            JSONObject jsonBody = new JSONObject();
//            JSONArray jsonArray = new JSONArray();
//            for (int i = 0; i < length; i++) {
//                JSONObject message = new JSONObject();
//                message.put("role", i % 2 == 0 ? "user" : "assistant");
//                message.put("content", messages[i]);
//                jsonArray.put(message);
//            }
//            jsonBody.put("messages", jsonArray);
//
//            // 使用工厂模式创建策略
//            // 这里可以根据实际需求实现具体的策略模式
//             SystemContentStrategy strategy = SystemContentStrategyFactory.createStrategy(scene);
//             jsonBody.put("system", strategy.getSystemContent());
//             //流式响应
//            jsonBody.put("stream",true);
//            RequestBody requestBody = RequestBody.create(mediaType, jsonBody.toString());
//            Request request = new Request.Builder()
//                    .url("https://aip.baidubce.com/rpc/2.0/ai_custom/v1/wenxinworkshop/chat/ernie-speed-128k?access_token=" + accessToken)
//                    .post(requestBody)
//                    .addHeader("Content-Type", "application/json")
//                    .build();
//
//            try (Response resp = HTTP_CLIENT.newCall(request).execute()) {
//                if (!resp.isSuccessful()) {
//                    throw new IOException("Unexpected code " + resp);
//                }
//                out.write(resp.body().bytes());
//            }
//        } catch (Exception e) {
//            e.printStackTrace();
//            throw new BaiYunException(ResultCode.ERROR, "系统内部错误，请联系管理员");
//        } finally {
//            try {
//                if (out != null) {
//                    out.close();
//                }
//            } catch (IOException e) {
//                e.printStackTrace();
//                throw new BaiYunException(ResultCode.ERROR, "系统内部错误，请联系管理员");
//            }
//        }
//    }
}